1Writer 過去メモ・タスク検索2
2024/11/02
メモとタスク両方を対象に検索
選択したタスクをカーソル位置に追加
タスクの複数選択
code:js
// 過去データ検索
const dayDifference = Math.floor((new Date() - new Date('2024-08-15')) / (1000 * 60 * 60 * 24));
const maxDaysToSearch = dayDifference; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 100; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
const start, end = editor.getSelectedLineRange(); // 現在の選択行の範囲を取得 let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードを決める(選択範囲があればそれを使用し、なければ入力を求める)
async function promptUserForKeywords() {
const selectedText = editor.getSelectedText(); // 選択されたテキストを取得
if (selectedText) {
return selectedText.split(/\s+/); // 選択範囲がある場合、そのままキーワードとして使用
} else {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(/\s+/)); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかメモかを判定する関数(タスクは - [x] またはメモは - hh:mm で始まる)
function isTaskOrMemo(line) {
return line.startsWith("- x ") || /^- \d{2}:\d{2} /.test(line); }
// タスク行やメモ行を解析し、各要素を抽出する
function parseLine(line) {
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const memoRegex = /^- (\d{2}:\d{2}) (.+)$/;
let match = line.match(taskRegex);
if (match) {
return {
type: "task",
startTime: match1 || null, actualTime: match3 || null, estimatedTime: match4 || null, content: match5 ? match5.trim() : "不明" };
}
match = line.match(memoRegex);
if (match) {
return {
type: "memo",
};
}
return null; // フォーマットが一致しない場合
}
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクとメモを検索する
async function searchTasksAndMemos(keywords, folderPath) {
let foundItems = [];
let currentDate = new Date();
let daysChecked = 0;
while (foundItems.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTaskOrMemo(line) && containsKeywords(line, keywords)) {
foundItems.push({ date: dateString, lineContent: line });
if (foundItems.length === maxTasksToFind) break;
}
}
}
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundItems;
}
// 検索結果をリスト形式で表示する
function displayTasksAndMemos(items) {
if (items.length === 0) {
ui.hudError("該当するタスクやメモが見つかりませんでした。");
} else {
const itemList = items.map(item => {
const parsedItem = parseLine(item.lineContent);
let title, subtitle, value;
if (parsedItem) {
if (parsedItem.type === "task") {
title = parsedItem.content;
value = \\${parsedItem.actualTime} ${parsedItem.content};
subtitle = ${item.date} ${parsedItem.startTime}-${parsedItem.endTime};
} else if (parsedItem.type === "memo") {
title = parsedItem.content;
value = ${parsedItem.time} ${parsedItem.content};
subtitle = ${item.date} ${parsedItem.time};
} else {
title = "不明";
subtitle = ${item.date};
value = "-";
}
} else {
title = "不明";
subtitle = ${item.date};
value = "-";
}
return { title, subtitle, value };
});
ui.list("検索結果", itemList.map(t => ${t.title}|${t.value}|${t.subtitle}), true, (selectedItems) => {
if (selectedItems) {
const itemsToInsert = selectedItems.join('\n');
editor.openFile(originalFilePath, 'edit', function () {
editor.setSelectedRange(cursorPosition0); editor.replaceSelection(${itemsToInsert}\n);
editor.setSelectedRange(cursorPosition0 + itemsToInsert.length); });
ui.hudSuccess("選択されたアイテムが挿入されました。");
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath();
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath;
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
const items = await searchTasksAndMemos(keywords, folderPath); // タスクとメモを検索
displayTasksAndMemos(items); // 結果を表示
reopenOriginalFile();
}
// 実行
main();